Skip to content

这是一个用来解析设备树的引用关系的脚本,比如一个xxx.dts可能会引用多个dtsi文件,我们可以将其打印出来。 例如:./dtsParse.sh arch/arm64/boot/dts/rockchip/rk3588-linux.dts arch/arm64/boot/dts/rockchip

下载文件dtsParse.sh

shell
#!/bin/bash

declare -g HEAD_FILES=()    #头文件
declare -g DT_FILES=()      #设备树文件

# 用于解析 DTS 文件及其引用的 DTSI 文件的函数


<NolebasePageProperties />




function parse_dts() {
    local current_dts_file="$1"    # 当前的 DTS 文件
    local current_dts_dir="$2"     # 当前 DTS 文件所在的目录
    local current_indent="$3"      # 缩进层次,用于打印树状结构
    local header_files=()

    echo "${current_indent}正在解析文件: $current_dts_file"
    DT_FILES+=("$current_dts_file");

    # 使用 grep 提取所有 #include 语句
    local includes=$(grep -E '^\s*#include\s+("|<)[^">]+("|>)' "$current_dts_file")

    header_files+=("xxx")

    # 先打印所有找到的 include 语句
    if [[ -n "$includes" ]]; then
        echo "${current_indent}找到以下包含文件:"
        while IFS= read -r line; do
            #echo "${current_indent}  $line"
            if [[ "$line" =~ ([a-zA-Z0-9_/.,-]+\.h) ]];then
                filename="${BASH_REMATCH[1]}"  # 提取匹配的头文件名
                HEAD_FILES+=("$filename")     # 添加到数组中
            fi
        done <<< "$includes"   # 将 includes 直接重定向到 while 循环
    else
        :
        echo "${current_indent}没有找到包含文件。"
    fi

    # 遍历所有找到的 include 语句并递归解析
    while IFS= read -r line; do
        # 从 include 语句中提取文件名
        if [[ "$line" =~ \"(.*)\" ]]; then
            local include_file="${BASH_REMATCH[1]}"
            
            # 标准化路径,避免出现双斜杠
            local include_path=$(realpath -m "$current_dts_dir/$include_file")

            if [[ -f "$include_path" ]]; then
                # 递归调用自身解析包含的文件,缩进增加
                parse_dts "$include_path" "$current_dts_dir" "    $current_indent"
            else
                echo -e "${current_indent}警告: \e[33m找不到包含文件 $include_file\e[0m"
            fi
        fi

    done <<< "$includes"
    
}

# 用于统计并打印二级节点的函数
function print_second_level_nodes() {
    local current_dts_file="$1"    # 当前的 DTS 文件
    local current_indent="$2"      # 缩进层次,用于打印树状结构

    # 初始化变量用于二级节点统计
    local level=0                  # 当前层次,初始为0表示文件最外层
    local second_level_node_count=0 # 二级节点计数
    local second_level_nodes=()     # 存储二级节点名称的数组

    # 重新遍历当前 DTS 文件以统计二级节点
    while IFS= read -r line; do
        # 删除行内注释(以 "//" 开头的注释)
        line=$(echo "$line" | sed 's/\/\/.*//')

        # 检测大括号的层次,"{" 表示进入下一层,"}" 表示回到上一层
        if [[ "$line" =~ "{" ]]; then
            level=$((level + 1))
        elif [[ "$line" =~ "}" ]]; then
            level=$((level - 1))
        fi

        # 检测二级节点(层次为2)
        if [[ $level -eq 2 && "$line" =~ ^[a-zA-Z0-9_,-]+: ]]; then
            second_level_node_count=$((second_level_node_count + 1))
            # 提取节点名称并加入到数组中
            local node_name=$(echo "$line" | cut -d ':' -f 1)
            second_level_nodes+=("$node_name")
        fi
    done < <(grep -v '/\*.*\*/' "$current_dts_file")  # 过滤掉多行注释

    # 打印二级节点数量和节点名称
    echo "${current_indent}二级节点数量: $second_level_node_count"
    if [[ $second_level_node_count -gt 0 ]]; then
        echo "${current_indent}二级节点名称:"
        for node in "${second_level_nodes[@]}"; do
            echo "${current_indent}  $node"
        done
    fi

    # 再次打印分隔符
    echo "${current_indent}======================"
}

# 检查传入的文件参数
if [[ $# -ne 2 ]]; then
    echo "功能:递归解析一个设备树中(dts,dtsi)的引用情况"
    echo "用法: $0 <dts文件路径> <dts目录>"
    exit 1
fi

# 获取传入的 DTS 文件路径和目录
input_dts_file=$(realpath $1)
input_dts_dir="$2"

# 检查文件是否存在
if [[ -f "$input_dts_file" && -d "$input_dts_dir" ]]; then
    # 调用解析函数,传入初始缩进为空字符串
    parse_dts "$input_dts_file" "$input_dts_dir" "";
else
    echo "错误: 找不到文件或目录"
    exit 1
fi

echo "*******************************************************************************"
echo ""

# 去重并排序相同前缀
unique_sorted_dt_files=($(printf "%s\n" "${DT_FILES[@]}" | sort | uniq | sort -t. -k1,1))

echo "其中的设备树文件:"
for dt_file in "${unique_sorted_dt_files[@]}"; do
    echo -e "\t$dt_file"
done

echo "*******************************************************************************"
echo ""

echo "==============================================================================="
echo ""

# 去重并排序相同前缀
unique_sorted_header_files=($(echo "${HEAD_FILES[@]}" | tr ' ' '\n' | sort | uniq | tr '\n' ' '))

echo "其中的头文件:"
for headers in "${unique_sorted_header_files[@]}"; do
    echo -e "\t$headers"
done

echo "==============================================================================="
echo ""

# 统计并打印二级节点
print_second_level_nodes "$input_dts_file" ""

贡献者

The avatar of contributor named as Px Px

页面历史

撰写